<template>
    <div>
        <InfiniteList 
            ref="infiniteListRef"
            :load-function="loadChatData" 
            data-field="threads" 
            pagination-field="pagination"
        >
            <template #default="{ data }">
                <div class="post-list-container">
                    <div v-for="post in data" :key="post.thread_id" class="post-item q-mb-md" @click="goThread(post.thread_id)">
                        <!-- 用户信息和发帖时间 -->
                        <div class="post-header">
                            <q-avatar size="40px" class="q-mr-sm">
                                <img v-if="post.User && post.User.avatar_urls.h" :src="post.User.avatar_urls.h" :alt="post.User.username">
                                <q-icon v-else name="person" size="48px" color="primary" />
                            </q-avatar>
                            <div class="post-user-info">
                                <div class="row items-center">
                                    <div class="text-subtitle2 text-weight-medium">{{ post.username }}</div>
                                    <q-chip color="primary" class="text-body2" text-color="white" dense v-if="post.User">{{ post.User.user_title }}</q-chip>
                                </div>
                                <div class="text-caption text-grey-6">{{ formatTime(post.last_post_date) }}</div>
                            </div>
                        </div>

                        <!-- 帖子标题 -->
                        <div class="post-title">
                            {{ post.title }}
                        </div>

                        <!-- 帖子正文 -->
                        <div v-if="post.content" class="post-content">
                            {{ truncateText(post.content, 100) }}
                        </div>

                        <!-- 内容加载中 -->
                        <div v-else-if="post.contentLoading" class="post-content-loading">
                            <q-skeleton type="text" width="100%" />
                            <q-skeleton type="text" width="80%" />
                            <q-skeleton type="text" width="60%" />
                        </div>

                        <!-- 图片缩略图 -->
                        <div v-if="post.images && post.images.length > 0" class="thumbnail-container">
                            <div class="thumbnail-grid" :class="getGridClass(post.images.length)">
                                <div v-for="(image, index) in post.images.slice(0, 9)" :key="index"
                                    class="thumbnail-item" @click.stop="openImagePreview(post.images, index)">
                                    <q-img :src="image.thumbnail || image.url" class="thumbnail-image" fit="cover"
                                        :ratio="getImageRatio(post.images.length)">
                                        <template v-slot:loading>
                                            <div class="flex flex-center" style="height: 100%;">
                                                <q-spinner-gears color="primary" size="20px" />
                                            </div>
                                        </template>
                                        <template v-slot:error>
                                            <div class="flex flex-center bg-grey-3 text-grey-6" style="height: 100%;">
                                                <q-icon name="broken_image" size="20px" />
                                            </div>
                                        </template>
                                    </q-img>

                                    <!-- 显示更多图片数量 -->
                                    <div v-if="index === 8 && post.images.length > 9" class="more-images-overlay">
                                        <div class="text-white text-subtitle2 text-weight-bold">+{{ post.images.length -
                                            9 }}
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <!-- 图片加载中 -->
                        <div v-else-if="post.imagesLoading" class="thumbnail-container">
                            <div class="thumbnail-grid grid-multiple">
                                <div v-for="i in 3" :key="i" class="thumbnail-item">
                                    <q-skeleton type="rect" width="100%" height="100px" />
                                </div>
                            </div>
                        </div>

                        <div>
                            <div class="text-grey-6 row justify-around q-mt-sm">
                                <q-btn flat size="sm">
                                    <q-icon name="visibility" class="q-mr-xs" />
                                    {{ post.view_count }}
                                </q-btn>
                                <q-btn flat size="sm" color="grey-6">
                                    <q-icon name="chat_bubble_outline" class="q-mr-xs" />
                                    {{ post.reply_count }}
                                </q-btn>
                                <q-btn flat size="sm" color="grey-6" @click="sharePost">
                                    <q-icon name="share" class="q-mr-xs" />
                                    分享
                                </q-btn>
                            </div>
                        </div>
                    </div>
                </div>
            </template>
        </InfiniteList>
        <ImageViewer v-model:images="previewImages" v-model:visible="showImagePreview" />
    </div>
</template>

<script setup>
import { ref } from 'vue'
import InfiniteList from './InfiniteList.vue'
import { formatTime } from 'src/utils/common'
import { ImageViewer } from 'tdesign-mobile-vue'
import { useRouter } from 'vue-router'
// 如果使用 Pinia，添加这行
// import { useThreadStore } from 'src/stores/thread'
// Props 定义
const props = defineProps({
    // 获取帖子列表的函数
    getThreadListFn: {
        type: Function,
        required: true
    },
    // 获取帖子详情的函数
    getThreadDetailFn: {
        type: Function,
        required: true
    },
    // 获取帖子详情时的额外参数
    threadDetailParams: {
        type: Object,
        default: () => ({ with_first_post: true })
    },
    // 获取帖子列表时的额外参数
    threadListParams: {
        type: Object,
        default: () => ({})
    },
    // 需要排除的图片URL前缀
    excludeImagePrefix: {
        type: String,
        default: 'https://dngamer.site/media/'
    },
    // 文本截取长度
    contentTruncateLength: {
        type: Number,
        default: 100
    }
})

// 用于存储所有帖子数据的映射
const postsMap = ref(new Map())

// InfiniteList 组件引用
const infiniteListRef = ref(null)

// 数据加载函数
const loadChatData = async (page) => {
    // 如果有额外参数，则合并参数；否则直接传递页码
    const result = Object.keys(props.threadListParams).length > 0 
        ? await props.getThreadListFn({ ...props.threadListParams, page })
        : await props.getThreadListFn(page)

    // 处理获取到的帖子列表
    if (result.threads && result.threads.length > 0) {
        // 为每个帖子添加加载状态
        result.threads.forEach(post => {
            // 添加加载状态标识
            post.contentLoading = true
            post.imagesLoading = true

            // 存储到映射中
            postsMap.value.set(post.thread_id, post)
        })

        // 异步加载详情
        loadPostDetails(result.threads)
    }

    return result
}

// 异步加载帖子详情
const loadPostDetails = async (posts) => {
    // 创建所有详情请求的 Promise 数组
    const detailPromises = posts.map(post => loadSinglePostDetail(post.thread_id))

    // 并发执行所有请求，但不等待全部完成
    // 使用 Promise.allSettled 来处理成功和失败的请求
    Promise.allSettled(detailPromises).then(results => {
        results.forEach((result, index) => {
            if (result.status === 'rejected') {
                console.error(`加载帖子 ${posts[index].thread_id} 详情失败:`, result.reason)
            }
        })
    })
}

// 加载单个帖子详情
const loadSinglePostDetail = async (threadId) => {
    try {
        const detail = await props.getThreadDetailFn(threadId, props.threadDetailParams)
        const post = postsMap.value.get(threadId)

        if (post && detail) {
            // 更新帖子内容
            if (detail.first_post) {
                post.content = detail.first_post.message
                post.message_parsed = detail.first_post.message_parsed
            }
            post.contentLoading = false

            // 从 BBCode 内容中提取图片
            const extractedImages = extractImagesFromBBCode(post.content)

            // 合并 API 返回的图片和从内容中提取的图片
            let allImages = []

            // 添加从内容中提取的图片
            if (extractedImages.length > 0) {
                // 避免重复图片
                const existingUrls = new Set(allImages.map(img => img.url))
                extractedImages.forEach(img => {
                    if (!existingUrls.has(img.url)) {
                        allImages.push(img)
                    }
                })
            }

            // 设置最终的图片数组
            if (allImages.length > 0) {
                post.images = allImages
            }
            post.imagesLoading = false
        }
    } catch (error) {
        console.error(`加载帖子 ${threadId} 详情失败:`, error)
        const post = postsMap.value.get(threadId)
        if (post) {
            post.contentLoading = false
            post.imagesLoading = false
        }
    }
}

// 从 BBCode 中提取图片链接
const extractImagesFromBBCode = (content) => {
    if (!content) return []

    const images = []

    // 匹配 [img]url[/img] 格式
    const imgRegex = /\[IMG\]([^[\]]+)\[\/IMG\]/gi
    let match
    while ((match = imgRegex.exec(content)) !== null) {
        const url = match[1].trim()
        if (!url.startsWith(props.excludeImagePrefix)) {
            images.push({
                url: url,
                thumbnail: url
            })
        }
    }

    // 匹配 [img=width,height]url[/img] 格式
    const imgWithSizeRegex = /\[IMG=\d+,\d+\]([^[\]]+)\[\/IMG\]/gi
    while ((match = imgWithSizeRegex.exec(content)) !== null) {
        const url = match[1].trim()
        if (!url.startsWith(props.excludeImagePrefix)) {
            images.push({
                url: url,
                thumbnail: url
            })
        }
    }

    // 匹配 [img width=xxx height=xxx]url[/img] 格式
    const imgWithAttrsRegex = /\[IMG[^\]]*\]([^[\]]+)\[\/IMG\]/gi
    while ((match = imgWithAttrsRegex.exec(content)) !== null) {
        const url = match[1].trim()
        if (!url.startsWith(props.excludeImagePrefix) && !images.some(img => img.url === url)) {
            images.push({
                url: url,
                thumbnail: url
            })
        }
    }

    // 去重处理
    const uniqueImages = []
    const seenUrls = new Set()

    images.forEach(img => {
        if (!seenUrls.has(img.url)) {
            seenUrls.add(img.url)
            uniqueImages.push(img)
        }
    })

    return uniqueImages
}

// 图片预览相关
const showImagePreview = ref(false)
const previewImages = ref([])
const previewIndex = ref(0)

// 截取文本
const truncateText = (text, maxLength) => {
    if (!text) return text;

    // 使用传入的截取长度
    const length = maxLength || props.contentTruncateLength

    // 移除BBCode标签（如[color=red][/color]、[b][/b]等）
    let processedText = text.replace(/\[.*?\]/g, '');

    // 移除HTML换行标签和换行符
    //processedText = processedText.replace(/<br\s*\/?>/gi, ' ').replace(/\n/g, ' ');

    // 合并多个连续空格为单个空格
    processedText = processedText.replace(/\s+/g, ' ').trim();

    // 检查长度并截断
    if (processedText.length <= length) return processedText;

    return processedText.substring(0, length) + '...';
};

// 获取网格布局类名
const getGridClass = (imageCount) => {
    if (imageCount === 1) return 'grid-single'
    if (imageCount === 2) return 'grid-double'
    return 'grid-multiple'
}

// 获取图片比例
const getImageRatio = (imageCount) => {
    if (imageCount === 1) return 16 / 9  // 单图使用16:9比例
    if (imageCount === 2) return 4 / 3   // 双图使用4:3比例
    return 1  // 多图使用1:1比例
}

// 打开图片预览
const openImagePreview = (images, index) => {
    previewImages.value = images
    previewIndex.value = index
    showImagePreview.value = true
}

// 刷新数据
const refresh = () => {
    // 清空帖子数据映射
    postsMap.value.clear()
    
    // 调用 InfiniteList 的刷新方法
    if (infiniteListRef.value && infiniteListRef.value.refresh) {
        infiniteListRef.value.refresh()
    }
}

// 暴露刷新方法给父组件
defineExpose({
    refresh
})
const router = useRouter()

const goThread = (id)=>{
    router.push('/thread/' + id)
}
</script>

<style scoped>
.post-list-container {
    width: 100%;
}

.post-item {
    border-radius: 12px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
    padding: 16px;
    margin-bottom: 12px;
    overflow: hidden;
}

.body--dark .post-item {
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
}

.post-header {
    display: flex;
    align-items: center;
    margin-bottom: 12px;
}

.post-user-info {
    flex: 1;
    min-width: 0;
}

.post-title {
    font-size: 16px;
    font-weight: 600;
    margin-bottom: 8px;
    line-height: 1.4;
}

.post-content {
    font-size: 14px;
    line-height: 1.5;
    margin-bottom: 12px;
    color: #555;
}

.body--dark .post-content {
    color:#e3e3e3;
}

.post-content-loading {
    margin-bottom: 12px;
}

.thumbnail-container {
    width: 100%;
    margin-top: 8px;
}

.thumbnail-grid {
    display: grid;
    gap: 4px;
    width: 100%;
}

/* 单图布局 */
.thumbnail-grid.grid-single {
    grid-template-columns: 1fr;
    max-width: 100%;
}

.thumbnail-grid.grid-single .thumbnail-item {
    border-radius: 8px;
    overflow: hidden;
    max-height: 200px;
}

/* 双图布局 */
.thumbnail-grid.grid-double {
    grid-template-columns: 1fr 1fr;
}

.thumbnail-grid.grid-double .thumbnail-item {
    border-radius: 8px;
    overflow: hidden;
    height: 120px;
}

/* 多图布局 */
.thumbnail-grid.grid-multiple {
    grid-template-columns: repeat(3, 1fr);
}

.thumbnail-grid.grid-multiple .thumbnail-item {
    border-radius: 6px;
    overflow: hidden;
    height: 100px;
}

.thumbnail-item {
    position: relative;
    cursor: pointer;
    background: #f5f5f5;
}

.thumbnail-image {
    width: 100%;
    height: 100%;
    border-radius: inherit;
    transition: transform 0.2s ease;
}

.thumbnail-item:hover .thumbnail-image {
    transform: scale(1.02);
}

.more-images-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: inherit;
    backdrop-filter: blur(2px);
}

/* 响应式调整 */
@media (max-width: 599px) {
    .q-pa-md {
        padding: 12px;
    }

    .post-item {
        padding: 12px;
        margin-bottom: 8px;
        border-radius: 8px;
    }

    .post-title {
        font-size: 15px;
    }

    .post-content {
        font-size: 13px;
    }

    .thumbnail-grid.grid-single .thumbnail-item {
        max-height: 180px;
    }

    .thumbnail-grid.grid-double .thumbnail-item {
        height: 100px;
    }

    .thumbnail-grid.grid-multiple .thumbnail-item {
        height: 80px;
    }
}

@media (max-width: 399px) {
    .q-pa-md {
        padding: 8px;
    }

    .post-item {
        padding: 10px;
    }

    .thumbnail-grid.grid-single .thumbnail-item {
        max-height: 160px;
    }

    .thumbnail-grid.grid-double .thumbnail-item {
        height: 90px;
    }

    .thumbnail-grid.grid-multiple .thumbnail-item {
        height: 70px;
    }
}
</style>

<style>
.t-image-viewer {
    z-index: 9999;
}
</style>